home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / gnucal.zip / gcal_rcc.c < prev    next >
C/C++ Source or Header  |  1995-12-20  |  73KB  |  2,009 lines

  1. /*
  2. *  gcal_rcc.c:  Checks whether date entry in file is valid.
  3. *
  4. *
  5. *  Copyright (C) 1994, 1995 Thomas Esken
  6. *
  7. *  This software doesn't claim completeness, correctness or usability.
  8. *  On principle I will not be liable for any damages or losses (implicit
  9. *  or explicit), which result from using or handling my software.
  10. *  If you use this software, you agree without any exception to this
  11. *  agreement, which binds you LEGALLY !!
  12. *
  13. *  This program is free software; you can redistribute it and/or modify
  14. *  it under the terms of the `GNU General Public License' as published by
  15. *  the `Free Software Foundation'; either version 2, or (at your option)
  16. *  any later version.
  17. *
  18. *  You should have received a copy of the `GNU General Public License'
  19. *  along with this program; if not, write to the:
  20. *    Free Software Foundation
  21. *    59 Temple Place, Suite 330
  22. *    Boston, MA 02111-1307  USA
  23. */
  24.  
  25.  
  26.  
  27. /*
  28. *  Include definition header file to see whether USE_RC is defined there.
  29. *    compile this module only if USE_RC is defined, otherwise skip it.
  30. */
  31. #include "gcal_tai.h"
  32.  
  33.  
  34.  
  35. #if USE_RC
  36. #  ifdef RCSID
  37. static char rcsid[]="$Id: gcal_rcc.c 0.39 1995/12/20 00:03:09 tom Exp $";
  38. #  endif
  39.  
  40.  
  41.  
  42. /*
  43. *  Include header files
  44. */
  45. #if HAVE_ASSERT_H
  46. #  include <assert.h>
  47. #endif
  48. #  if HAVE_CTYPE_H
  49. #    include <ctype.h>
  50. #  endif
  51. #  include "gcal.h"
  52.  
  53.  
  54.  
  55. /*
  56. *  Function prototypes
  57. */
  58. #  if __cplusplus
  59. extern "C"
  60. {
  61. #  endif
  62. /*
  63. ************************************************** Defined in `gcal_rc.c'
  64. */
  65. IMPORT char *
  66. rc_get_date __P_((      char *ptr_char,
  67.                         Bool *is_weekday_mode,
  68.                         int  *d,
  69.                         int  *m,
  70.                         int  *y,
  71.                         int  *n,
  72.                         int  *len,
  73.                         char *hc,
  74.                         int  *hn,
  75.                         int  *hwd,
  76.                   const char *filename,
  77.                   const int   line,
  78.                   const char *line_buffer,
  79.                   const Bool  on_error_exit));
  80. IMPORT Bool
  81. precomp_nth_wd __P_((      int         diff,
  82.                      const int         wd,
  83.                            int        *n,
  84.                            int        *day,
  85.                            int        *month,
  86.                            int        *year,
  87.                      const Cmode_enum  mode));
  88. IMPORT Bool
  89. precomp_date __P_((      int         diff,
  90.                    const int         wd,
  91.                          int        *day,
  92.                          int        *month,
  93.                    const int         year,
  94.                    const Cmode_enum  mode));
  95. IMPORT void
  96. nth_weekday_of_month __P_((      int  *d,
  97.                                  int  *m,
  98.                                  int  *y,
  99.                            const int  *n,
  100.                                  Bool *is_weekday_mode));
  101. IMPORT void
  102. prev_date __P_((int *day,
  103.                 int *month,
  104.                 int *year));
  105. IMPORT void
  106. next_date __P_((int *day,
  107.                 int *month,
  108.                 int *year));
  109. IMPORT void
  110. num2date __P_((Ulint  julian_days,
  111.                int   *day,
  112.                int   *month,
  113.                int   *year));
  114. IMPORT Slint
  115. d_between __P_((const int d1,
  116.                 const int m1,
  117.                 const int y1,
  118.                 const int d2,
  119.                 const int m2,
  120.                 const int y2));
  121. IMPORT Slint
  122. w_between __P_((const int d1,
  123.                 const int m1,
  124.                 const int y1,
  125.                 const int d2,
  126.                 const int m2,
  127.                 const int y2));
  128. IMPORT Slint
  129. m_between __P_((const int m1,
  130.                 const int y1,
  131.                 const int m2,
  132.                 const int y2));
  133. /*
  134. ************************************************** Defined in `gcal_utl.c'
  135. */
  136. IMPORT VOID_PTR
  137. my_malloc __P_((const int   amount,
  138.                 const int   exit_status,
  139.                 const char *module_name,
  140.                 const int   module_line,
  141.                 const char *var_name,
  142.                 const int   var_contents));
  143. IMPORT VOID_PTR
  144. my_realloc __P_((      VOID_PTR  ptr_memblock,
  145.                  const int       amount,
  146.                  const int       exit_status,
  147.                  const char     *module_name,
  148.                  const int       module_line,
  149.                  const char     *var_name,
  150.                  const int       var_contents));
  151. IMPORT void
  152. my_error __P_((const int   exit_status,
  153.                const char *module_name,
  154.                const int   module_line,
  155.                const char *var_name,
  156.                const int   var_contents));
  157. IMPORT Bool
  158. get_actual_date __P_((void));
  159. #  if !USE_GER
  160. IMPORT const char *
  161. day_suffix __P_((int day));
  162. #  endif
  163. IMPORT const char *
  164. short_month_name __P_((const int month));
  165. IMPORT Ulint
  166. date2num __P_((const int day,
  167.                const int month,
  168.                const int year));
  169. IMPORT Bool
  170. jdate2sdate __P_((      int  jdate,
  171.                   const int  is_leap_year,
  172.                         int *day,
  173.                         int *month));
  174. IMPORT int
  175. weekday_of_date __P_((const int day,
  176.                       const int month,
  177.                       const int year));
  178. IMPORT int
  179. day_of_year __P_((const int day,
  180.                   const int month,
  181.                   const int year));
  182. IMPORT int
  183. days_of_february __P_((const int year));
  184. IMPORT Bool
  185. valid_date __P_((const int day,
  186.                  const int month,
  187.                  const int year));
  188. IMPORT int
  189. week_number __P_((const int day,
  190.                   const int month,
  191.                   const int year));
  192. IMPORT int
  193. knuth_easter_formula __P_((const int year));
  194. /*
  195. ************************************************** Defined in `gcal_rcc.c'
  196. */
  197. EXPORT void
  198. rc_check __P_((      char *line_buffer,
  199.                const char *filename,
  200.                      int  *line,
  201.                      int  *rc_elems,
  202.                      int   day,
  203.                      int   ed,
  204.                const int   wd));
  205. #  if __cplusplus
  206. }
  207. #  endif
  208.  
  209.  
  210.  
  211. /*
  212. *  Declare public(extern) variables
  213. */
  214. IMPORT const int    dvec[MONTH_MAX];          /* Amount of days in months' */
  215. IMPORT Hls_struct   ehls1s;                   /* Effective hls 1 start (current day) */
  216. IMPORT Hls_struct   ehls1e;                   /* Effective hls 1 end (current day) */
  217. IMPORT Dvar_struct  rc_dvar[RC_DVAR_MAX];     /* Date variables a[=`mmdd']...z[] (`yyyy'@{a|b|...|z}[[-]<n>]) */
  218. #if HAVE_ASSERT_H
  219. IMPORT Uint         testval;                  /* Set to INT_MAX for checking the maximum table range */
  220. #endif
  221. IMPORT int          len_year_max;             /* String length of the maximum year able to compute */
  222. IMPORT int          start_day;                /* -s<0,1...7|day name> */
  223. IMPORT int          month;                    /* Current month */
  224. IMPORT int          year;                     /* Current year */
  225. IMPORT int          rc_elems_max;             /* Actual size of `rc_table' */
  226. IMPORT int          rc_have_today_in_list;    /* [-c]d */
  227. IMPORT int          act_min;                  /* Actual minute */
  228. IMPORT int          act_hour;                 /* Actual hour */
  229. IMPORT int          act_day;                  /* Actual day */
  230. IMPORT int          act_month;                /* Actual month */
  231. IMPORT int          act_year;                 /* Actual year */
  232. IMPORT int          fiscal_month;             /* Starting month of a fiscal year */
  233. IMPORT int          is_leap_year;             /* Is current year a leap year? */
  234. IMPORT int          len_fil_wt;               /* Filler length of week number text */
  235. IMPORT char         s[MAXLEN+1];              /* General purpose text buffer */
  236. IMPORT char         s2[MAXLEN+1];             /* General purpose text buffer */
  237. IMPORT char       **rc_table;                 /* Stores the valid fixed date texts */
  238. IMPORT Bool         rc_enable_fn_flag;        /* [-c]a */
  239. IMPORT Bool         rc_weekno_flag;           /* [-c]k */
  240. IMPORT Bool         rc_period_list;           /* [-c]l */
  241. IMPORT Bool         rc_period_flag;           /* [-c]<<<<n>>[<d|w|+|-]>|`mmdd'|`mmww[w]'<n>> */
  242. IMPORT Bool         rc_tomorrow_flag;         /* [-c]t */
  243. IMPORT Bool         rc_week_flag;             /* [-c]w */
  244. IMPORT Bool         rc_month_flag;            /* [-c]m */
  245. IMPORT Bool         rc_year_flag;             /* [-c]y */
  246. IMPORT Bool         rc_week_year_flag;        /* [-c<<n>>]w */
  247. IMPORT Bool         rc_forwards_flag;         /* [-c<<n>|w|m|y>]+ */
  248. IMPORT Bool         rc_backwards_flag;        /* [-c<<n>|w|m|y>]- */
  249. IMPORT Bool         is_date_given;            /* Is a date given in the command line? */
  250. IMPORT Bool         highlight_flag;           /* -H<yes> or -H<no> */
  251. IMPORT Bool         is_3month_mode;           /* Argument is "." or ".+" or ".-" */
  252. IMPORT Bool         is_3month_mode2;          /* Argument is ".." -> current quarter of actual year */
  253. IMPORT Bool         adate_set;                /* [-c]<n>w and actual date modified */
  254.  
  255.  
  256.  
  257. #  ifdef ANSI_PROTO
  258. EXPORT void
  259. rc_check (      char *line_buffer,
  260.           const char *filename,
  261.                 int  *line,
  262.                 int  *rc_elems,
  263.                 int   day,
  264.                 int   ed,
  265.           const int   wd)
  266. #  else /* !ANSI_PROTO */
  267.    EXPORT void
  268. rc_check (line_buffer, filename, line, rc_elems, day, ed, wd)
  269.          char *line_buffer;
  270.    const char *filename;
  271.          int  *line;
  272.          int  *rc_elems;
  273.          int   day;
  274.          int   ed;
  275.    const int   wd;
  276. #  endif /* !ANSI_PROTO */
  277. /*
  278.    Checks whether a single line of resource file resp.,
  279.      eternal holiday must be displayed
  280. */
  281. {
  282.    register int    i;
  283.    register int    j;
  284.    register int    incr_year=0;
  285.    register int    decr_year=0;
  286.    register int    print_twice;
  287.    register int    tmp_month=month;
  288.    auto     int    d;
  289.    auto     int    m;
  290.    auto     int    y;
  291.    auto     int    n;
  292.    auto     int    hn;
  293.    auto     int    hhn;
  294.    auto     int    hwd;
  295.    auto     int    hhwd;
  296.    auto     int    len;
  297.    auto     int    dd;
  298.    auto     int    mm;
  299.    auto     int    yy;
  300.    auto     int    nn;
  301.    auto     int    d2;
  302.    auto     int    m2;
  303.    static   char   str[MAXLEN+1];
  304.    auto     char  *ptr_char;
  305.    auto     char   hc;
  306.    auto     char   hhc;
  307.    auto     Bool   print_line;
  308.    auto     Bool   is_weekday_mode;
  309.    auto     Bool   is_2dvar=FALSE;
  310.    auto     Bool   is_2easter=FALSE;
  311.    auto     Bool   is_valid_date=TRUE;
  312.    auto     Bool   change_month=FALSE;
  313.  
  314.  
  315.    ptr_char = rc_get_date (line_buffer, &is_weekday_mode, &d, &m, &y, &n, &len,
  316.                            &hc, &hn, &hwd, filename, *line, line_buffer, TRUE);
  317.    if (len < 1)
  318.      /*
  319.         Error, invalid date field given
  320.      */
  321.      my_error (123, filename, *line, line_buffer, 0);
  322.    if (!month)
  323.     {
  324.       month = act_month;
  325.       change_month = TRUE;
  326.     }
  327.    if (d)
  328.     {
  329.       /*
  330.          If special value 99 for day `d' is given,
  331.            set day to last day of month
  332.       */
  333.       if (d == 99)
  334.        {
  335.          if (m)
  336.           {
  337.             if (m == 2)
  338.               d = days_of_february ((y) ? y : year);
  339.             else
  340.               d = dvec[m-1];
  341.           }
  342.          else
  343.           {
  344.             if (month == 2)
  345.               d = days_of_february ((y) ? y : year);
  346.             else
  347.               d = dvec[month-1];
  348.           }
  349.        }
  350.       is_valid_date = valid_date (d, (m) ? m : month, (y) ? y : year);
  351.     }
  352.    if (!is_valid_date)
  353.     {
  354.       if (   y == -1
  355.           || (   !y
  356.               && (   (   (   m == 2
  357.                           || (   !m
  358.                               && (month == 2)))
  359.                       && (d == 29))
  360.                   || (   !m
  361.                       && (d <= 31))))
  362.           || (   y
  363.               && !m
  364.               && (d <= 31)))
  365.         is_valid_date = TRUE;   /* If no month/year entry encoded, ignore that date */
  366.       else
  367.         /*
  368.            Invalid date field given
  369.         */
  370.         my_error (121, filename, *line, line_buffer, 0);
  371.     }
  372.    /*
  373.       If "n'th weekday of month" field is encoded, compute the according date
  374.    */
  375.    if (n)
  376.      nth_weekday_of_month (&d, &m, &y, &n, &is_weekday_mode);
  377.    else
  378.      /*
  379.         If @e... Easter holiday date part is given, compute the according date
  380.      */
  381.      if (hc == RC_EASTER_CHAR)
  382.       {
  383.         register int  epy=knuth_easter_formula (year-1);   /* Date of Easter Sunday in previous year */
  384.         register int  eay=knuth_easter_formula (year);     /* Date of Easter Sunday in current year */
  385.         register int  eny=knuth_easter_formula (year+1);   /* Date of Easter Sunday in next year */
  386.  
  387.  
  388.         if (fiscal_month > MONTH_MIN)
  389.          {
  390.            /*
  391.               Precalculate number of days in last month of fiscal year
  392.            */
  393.            if (fiscal_month-1 == 2)
  394.              i = days_of_february (year+1);
  395.            else
  396.              i = dvec[fiscal_month-2];
  397.            /*
  398.               Manage fiscal year request
  399.            */
  400.            if (year == EASTER_MIN-1)
  401.             {
  402.               j = day_of_year (i, fiscal_month-1, year+1);
  403.               if (hn+eny <= j)
  404.                {
  405.                  if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))
  406.                    y = -1;
  407.                }
  408.               else
  409.                 y = -1;
  410.             }
  411.            else
  412.             {
  413.               j = day_of_year (DAY_MIN, fiscal_month, year);
  414.               if (hn+eay >= j)
  415.                {
  416.                  if (!precomp_date (hn, hwd, &d, &m, year, EAster))
  417.                    y = -1;
  418.                  else
  419.                   {
  420.                     /*
  421.                        Check whether event occurs in next year, too
  422.                     */
  423.                     j = day_of_year (i, fiscal_month-1, year+1);
  424.                     if (   !is_3month_mode
  425.                         && !is_3month_mode2
  426.                         && (hn+eny <= j))
  427.                       is_2easter = TRUE;
  428.                   }
  429.                }
  430.               else
  431.                {
  432.                  if (   is_3month_mode
  433.                      || is_3month_mode2)
  434.                   {
  435.                     if (fiscal_month >= MONTH_MAX-1)
  436.                      {
  437.                        j = dvec[MONTH_MIN-1];
  438.                        if (fiscal_month == MONTH_MAX)
  439.                          j += days_of_february (year+1) + is_leap_year;
  440.                        if (hn+eny <= j)
  441.                         {
  442.                           if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))
  443.                             y = -1;
  444.                         }
  445.                        else
  446.                          y = -1;
  447.                      }
  448.                     else
  449.                       y = -1;
  450.                   }
  451.                  else
  452.                   {
  453.                     j = day_of_year (i, fiscal_month-1, year+1);
  454.                     if (hn+eny <= j)
  455.                      {
  456.                        if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))
  457.                          y = -1;
  458.                      }
  459.                     else
  460.                       y = -1;
  461.                   }
  462.                }
  463.             }
  464.          }
  465.         else
  466.           /*
  467.              Manage -c0w request resp.,
  468.                -cw in case date is in first days of january
  469.           */
  470.           if (day < DAY_MIN)
  471.            {
  472.              j = DAY_LAST + (days_of_february (year-1) == 29);
  473.              if (   (hn+epy >= j+day)
  474.                  && (hn+epy <= j))
  475.               {
  476.                 if (!precomp_date (hn, hwd, &d, &m, year-1, EAster))
  477.                   y = -1;
  478.               }
  479.              else
  480.               {
  481.                 if (hn+eay < ed)
  482.                  {
  483.                    if (!precomp_date (hn, hwd, &d, &m, year, EAster))
  484.                      y = -1;
  485.                  }
  486.                 else
  487.                   y = -1;
  488.               }
  489.            }
  490.           else
  491.             /*
  492.                Manage -c99w (-c52w | -c53w) request resp.,
  493.                  -ct or -cw in case date is in last days of december
  494.             */
  495.             if (ed > DAY_LAST+is_leap_year+1)
  496.              {
  497.                j = DAY_LAST + is_leap_year;
  498.                if (   (hn+eay >= day)
  499.                    && (hn+eay <= j))
  500.                 {
  501.                   if (!precomp_date (hn, hwd, &d, &m, year, EAster))
  502.                     y = -1;
  503.                 }
  504.                else
  505.                 {
  506.                   if (hn+eny < ed-j)
  507.                    {
  508.                      if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))
  509.                        y = -1;
  510.                    }
  511.                   else
  512.                     y = -1;
  513.                 }
  514.              }
  515.             else
  516.               /*
  517.                  All other "ordinary" requests...
  518.               */
  519.               if (!precomp_date (hn, hwd, &d, &m, year, EAster))
  520.                 y = -1;
  521.       }
  522.      else
  523.        /*
  524.           If @`dvar'... date part is given, compute the according date
  525.        */
  526.        if (islower(hc))
  527.         {
  528.           if (fiscal_month > MONTH_MIN)
  529.            {
  530.              register int  date_dvar=day_of_year (d, m, year);
  531.  
  532.  
  533.              /*
  534.                 Precalculate number of days in last month of fiscal year
  535.              */
  536.              if (fiscal_month-1 == 2)
  537.                i = days_of_february (year+1);
  538.              else
  539.                i = dvec[fiscal_month-2];
  540.              /*
  541.                 Manage fiscal year request
  542.              */
  543.              j = day_of_year (DAY_MIN, fiscal_month, year);
  544.              /*
  545.                 Buffer day and month
  546.              */
  547.              d2 = d;
  548.              m2 = m;
  549.              if (hn+date_dvar >= j)
  550.               {
  551.                 if (!precomp_date (hn, hwd, &d, &m, year, DVar))
  552.                   y = -1;
  553.                 else
  554.                  {
  555.                    /*
  556.                       Check whether event occurs in next year, too
  557.                    */
  558.                    j = day_of_year (i, fiscal_month-1, year+1);
  559.                    if (   !is_3month_mode
  560.                        && !is_3month_mode2
  561.                        && (hn+date_dvar <= j))
  562.                      is_2dvar = TRUE;
  563.                  }
  564.               }
  565.              else
  566.               {
  567.                 if (   is_3month_mode
  568.                     || is_3month_mode2)
  569.                  {
  570.                    if (fiscal_month >= MONTH_MAX-1)
  571.                     {
  572.                       j = dvec[MONTH_MIN-1];
  573.                       if (fiscal_month == MONTH_MAX)
  574.                         j += days_of_february (year+1) + is_leap_year;
  575.                       if (hn+date_dvar <= j)
  576.                        {
  577.                          if (!precomp_date (hn, hwd, &d, &m, year+1, DVar))
  578.                            y = -1;
  579.                        }
  580.                       else
  581.                         y = -1;
  582.                     }
  583.                    else
  584.                      y = -1;
  585.                  }
  586.                 else
  587.                  {
  588.                    j = day_of_year (i, fiscal_month-1, year+1);
  589.                    if (hn+date_dvar <= j)
  590.                     {
  591.                       if (!precomp_date (hn, hwd, &d, &m, year+1, DVar))
  592.                         y = -1;
  593.                     }
  594.                    else
  595.                      y = -1;
  596.                  }
  597.               }
  598.            }
  599.           else
  600.             /*
  601.                All other "ordinary" requests...
  602.             */
  603.             if (!precomp_date (hn, hwd, &d, &m, year, DVar))
  604.               y = -1;
  605.         }
  606.        else
  607.          /*
  608.             If 0*d|w<n>[ww[w]] date part is given, compute the according date
  609.          */
  610.          if (   hc == 'D'
  611.              || hc == 'W')
  612.           {
  613.             y = year;
  614.             if (precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,
  615.                                 ((hc == 'D') ? DAy : WEek)))
  616.              {
  617.                register int  date_dvar=day_of_year (d, m, y);
  618.  
  619.  
  620.                if (fiscal_month > MONTH_MIN)
  621.                 {
  622.                   /*
  623.                      Precalculate number of days in last month of fiscal year
  624.                   */
  625.                   if (fiscal_month-1 == 2)
  626.                     i = days_of_february (year+1);
  627.                   else
  628.                     i = dvec[fiscal_month-2];
  629.                   /*
  630.                      Manage fiscal year request
  631.                   */
  632.                   j = day_of_year (DAY_MIN, fiscal_month, year);
  633.                   /*
  634.                      Buffer day and month
  635.                   */
  636.                   d2 = d;
  637.                   m2 = m;
  638.                   if (hn+date_dvar >= j)
  639.                    {
  640.                      /*
  641.                         Check whether event occurs in next year, too
  642.                      */
  643.                      j = day_of_year (i, fiscal_month-1, year+1);
  644.                      if (   !is_3month_mode
  645.                          && !is_3month_mode2
  646.                          && (hn+date_dvar <= j))
  647.                        is_2dvar = TRUE;
  648.                    }
  649.                   else
  650.                    {
  651.                      if (   is_3month_mode
  652.                          || is_3month_mode2)
  653.                       {
  654.                         if (fiscal_month >= MONTH_MAX-1)
  655.                          {
  656.                            j = dvec[MONTH_MIN-1];
  657.                            if (fiscal_month == MONTH_MAX)
  658.                              j += days_of_february (year+1) + is_leap_year;
  659.                            if (hn+date_dvar <= j)
  660.                             {
  661.                               y++;
  662.                               (void)precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,
  663.                                                     ((hc == 'D') ? DAy : WEek));
  664.                             }
  665.                            else
  666.                              y = -1;
  667.                          }
  668.                         else
  669.                           y = -1;
  670.                       }
  671.                      else
  672.                       {
  673.                         j = day_of_year (i, fiscal_month-1, year+1);
  674.                         if (hn+date_dvar <= j)
  675.                          {
  676.                            y++;
  677.                            (void)precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,
  678.                                                  ((hc == 'D') ? DAy : WEek));
  679.                          }
  680.                         else
  681.                           y = -1;
  682.                       }
  683.                    }
  684.                 }
  685.              }
  686.           }
  687.    /*
  688.       Check whether current line must be displayed
  689.    */
  690.    print_line = FALSE;
  691.    print_twice = 1;
  692.    if (y >= 0)
  693.     {
  694.       if (   is_date_given
  695.           || (   (year != act_year)
  696.               && (day > 0))
  697.           || (   (   month
  698.                   && (month != act_month))
  699.               && (year == act_year)))
  700.        {
  701.          /*
  702.             NOT in simple month-/year mode (an explicit date is given in command line):
  703.               manage -c[...] arguments
  704.          */
  705.          if (   d
  706.              && !is_weekday_mode)
  707.           {
  708.             incr_year = (   (fiscal_month > MONTH_MIN)
  709.                          && (m < fiscal_month)
  710.                          && (   !y
  711.                              || y == year+1));
  712.             if (   is_date_given
  713.                 && month
  714.                 && !change_month
  715.                 && !m)
  716.              {
  717.                m = month;
  718.                is_valid_date = valid_date (d, m, (y) ? y : year);
  719.              }
  720.             if (   is_valid_date
  721.                 && (   !y
  722.                     || y-incr_year == year)
  723.                 && m
  724.                 && d)
  725.              {
  726.                if (   month
  727.                    && !change_month)
  728.                 {
  729.                   if (m == month)
  730.                    {
  731.                      if (   !is_leap_year
  732.                          && (m == 2)
  733.                          && (d == 29))
  734.                        ;   /* If year is no leap year, ignore that date */
  735.                      else
  736.                        print_line = TRUE;
  737.                    }
  738.                 }
  739.                else
  740.                 {
  741.                   if (fiscal_month > MONTH_MIN)
  742.                    {
  743.                      if (   (   incr_year
  744.                              && (year < YEAR_MAX))
  745.                          || (   (m >= fiscal_month)
  746.                              && (   !y
  747.                                  || y == year)))
  748.                       {
  749.                         if (   !(days_of_february (year+incr_year)==29)
  750.                             && (m == 2)
  751.                             && (d == 29))
  752.                           ;   /* If year is no leap year, ignore that date */
  753.                         else
  754.                           print_line = TRUE;
  755.                       }
  756.                    }
  757.                   else
  758.                    {
  759.                      if (   !is_leap_year
  760.                          && (m == 2)
  761.                          && (d == 29))
  762.                        ;   /* If year is no leap year, ignore that date */
  763.                      else
  764.                        print_line = TRUE;
  765.                    }
  766.                 }
  767.              }
  768.           }
  769.        }
  770.       else
  771.        {
  772.          /*
  773.             Simple month-/year mode (NO explicit date is given in command line):
  774.               manage [-c[...]]w|m|y[+|-] arguments
  775.          */
  776.          if (   (   rc_period_flag
  777.                  || rc_week_flag
  778.                  || rc_month_flag
  779.                  || rc_year_flag)
  780.              && !is_date_given
  781.              && (   !y
  782.                  || y == year
  783.                  || (   rc_week_flag
  784.                      && (   (   (year+1 <= YEAR_MAX)
  785.                              && (ed > DAY_LAST+is_leap_year+1))
  786.                          || (   (year-1 >= YEAR_MIN)
  787.                              && (day < DAY_MIN))))))
  788.           {
  789.             register int  td;
  790.  
  791.  
  792.             if (   m
  793.                 && d)
  794.              {
  795.                if (   rc_week_flag
  796.                    && !y
  797.                    && (m != month))
  798.                 {
  799.                   if (   (ed > DAY_LAST+is_leap_year+1)
  800.                       && !adate_set
  801.                       && (   rc_forwards_flag
  802.                           || (   !rc_forwards_flag
  803.                               && !rc_backwards_flag)))
  804.                     y = year + 1;
  805.                   else
  806.                     if (   (day < DAY_MIN)
  807.                         && !adate_set
  808.                         && (   rc_backwards_flag
  809.                             || (   !rc_forwards_flag
  810.                                 && !rc_backwards_flag)))
  811.                       y = year - 1;
  812.                 }
  813.                if (   y < YEAR_MIN
  814.                    || y > YEAR_MAX)
  815.                 {
  816.                   if (adate_set)
  817.                    {
  818.                      if (m == month)
  819.                       {
  820.                         if (day < DAY_MIN)
  821.                           y = year - 1;
  822.                       }
  823.                      else
  824.                       {
  825.                         if (ed > DAY_LAST+is_leap_year+1)
  826.                           y = year + 1;
  827.                       }
  828.                      if (   y < YEAR_MIN
  829.                          || y > YEAR_MAX)
  830.                        y = year;
  831.                    }
  832.                   else
  833.                     y = year;
  834.                 }
  835.              }
  836.             if (   (   rc_week_flag
  837.                     && is_weekday_mode)
  838.                 || (   !is_weekday_mode
  839.                     && (   y
  840.                         || m
  841.                         || d)))
  842.              {
  843.                /*
  844.                   Respect short day name entry `yyyymmww[w]' ... (ww[w]==short dayname)
  845.                */
  846.                if (   rc_week_flag
  847.                    && is_weekday_mode)
  848.                 {
  849.                   static struct {
  850.                                   char day[DAY_MAX];
  851.                                   char dst[DAY_MAX];
  852.                                 } wday_list;
  853.                   static Bool     fill_wday_list=FALSE;
  854.  
  855.  
  856.                   j = 0;
  857.                   if (!fill_wday_list)
  858.                    {
  859.                      if (   rc_forwards_flag
  860.                          || (   !rc_forwards_flag
  861.                              && !rc_backwards_flag))
  862.                       {
  863.                         i = wd;
  864.                         LOOP
  865.                          {
  866.                            wday_list.day[i-1] = (char)i;
  867.                            wday_list.dst[i-1] = (char)j++;
  868.                            i++;
  869.                            if (i > DAY_MAX)
  870.                              i = DAY_MIN;
  871.                            if (i == start_day)
  872.                              break;
  873.                          }
  874.                       }
  875.                      j = 0;
  876.                      if (   rc_backwards_flag
  877.                          || (   !rc_forwards_flag
  878.                              && !rc_backwards_flag))
  879.                       {
  880.                         i = wd;
  881.                         LOOP
  882.                          {
  883.                            if (i < DAY_MIN)
  884.                              i = DAY_MAX;
  885.                            wday_list.day[i-1] = (char)i;
  886.                            wday_list.dst[i-1] = (char)++j;
  887.                            if (i == start_day)
  888.                              break;
  889.                            i--;
  890.                          }
  891.                       }
  892.                      fill_wday_list = TRUE;
  893.                    }
  894.                   if (wday_list.day[d-1])
  895.                    {
  896.                      yy = year;
  897.                      if (rc_week_year_flag)
  898.                       {
  899.                         j = day;
  900.                         if (day < 1)
  901.                          {
  902.                            yy = year - 1;
  903.                            j += (DAY_LAST + (days_of_february (yy) == 29));
  904.                          }
  905.                         (void)jdate2sdate (j, (days_of_february (yy)==29), &dd, &mm);
  906.                       }
  907.                      else
  908.                       {
  909.                         dd = act_day;
  910.                         mm = month;
  911.                       }
  912.                      if (rc_forwards_flag)
  913.                        for (i=0 ; i < wday_list.dst[d-1] ; i++)
  914.                          next_date (&dd, &mm, &yy);
  915.                      else
  916.                        if (rc_backwards_flag)
  917.                          for (i=1 ; i < wday_list.dst[d-1] ; i++)
  918.                            prev_date (&dd, &mm, &yy);
  919.                        else
  920.                         {
  921.                           i = SYEAR(d, start_day);
  922.                           j = SYEAR(wd, start_day);
  923.                           if (i-j <= 0)
  924.                             for (i=1 ; i < wday_list.dst[d-1] ; i++)
  925.                               prev_date (&dd, &mm, &yy);
  926.                           else
  927.                             for (i=0 ; i < wday_list.dst[d-1] ; i++)
  928.                               next_date (&dd, &mm, &yy);
  929.                         }
  930.                      if (   (   !m
  931.                              || m == mm)
  932.                          && (   !y
  933.                              || y == yy))
  934.                       {
  935.                         d = dd;
  936.                         m = mm;
  937.                         y = yy;
  938.                       }
  939.                      else
  940.                        y = -1;
  941.                    }
  942.                   else
  943.                     y = -1;
  944.                 }
  945.                if (   rc_week_flag
  946.                    && (y >= 0)
  947.                    && (   day < DAY_MIN
  948.                        || ed > DAY_LAST+is_leap_year+1))
  949.                 {
  950.                   if (   (   rc_backwards_flag
  951.                           || (   !rc_forwards_flag
  952.                               && !rc_backwards_flag))
  953.                       && (y == year-1)
  954.                       && m
  955.                       && d)
  956.                    {
  957.                      ed = DAY_LAST + (days_of_february (y) == 29);
  958.                      day = ed + day;
  959.                      td = day_of_year (d, m, y);
  960.                      if (   (td <= ed)
  961.                          && (td >= day))
  962.                       {
  963.                         decr_year = 1;
  964.                         print_line = TRUE;
  965.                       }
  966.                    }
  967.                   else
  968.                     if (   (   rc_forwards_flag
  969.                             || (   !rc_forwards_flag
  970.                                 && !rc_backwards_flag))
  971.                         && (y == year+1)
  972.                         && m
  973.                         && d)
  974.                      {
  975.                        td = day_of_year (d, m, y) + DAY_LAST + is_leap_year;
  976.                        if (   (td < ed)
  977.                            && (td >= day))
  978.                         {
  979.                           incr_year = 1;
  980.                           print_line = TRUE;
  981.                         }
  982.                      }
  983.                     else
  984.                      {
  985.                        if (   (   y == year
  986.                                || (   (y == year-1)
  987.                                    && !rc_forwards_flag)
  988.                                || (   (y == year+1)
  989.                                    && !rc_backwards_flag))
  990.                            && m
  991.                            && d)
  992.                         {
  993.                           td = day_of_year (d, m, y);
  994.                           if (   (td < ed)
  995.                               && (td >= day))
  996.                             print_line = TRUE;
  997.                         }
  998.                        else
  999.                          if (d)
  1000.                           {
  1001.                             td = 0;
  1002.                             m = month;
  1003.                             if (day < DAY_MIN)
  1004.                              {
  1005.                                if (   !y
  1006.                                    || y == year
  1007.                                    || y == year-1)
  1008.                                 {
  1009.                                   if (adate_set)
  1010.                                     i = dvec[MONTH_MAX-1] + day - 1;
  1011.                                   else
  1012.                                     i = dvec[MONTH_MAX-1] + act_day - (SYEAR(wd, start_day));
  1013.                                   if (d > i)
  1014.                                    {
  1015.                                      m = MONTH_MAX;
  1016.                                      if (!y)
  1017.                                        y = year - 1;
  1018.                                      if (y == year)
  1019.                                        td = day_of_year (d, m, year);
  1020.                                      else
  1021.                                       {
  1022.                                         ed = DAY_LAST + (days_of_february (y) == 29);
  1023.                                         day = ed + day;
  1024.                                         td = day_of_year (d, m, y);
  1025.                                         decr_year = 1;
  1026.                                       }
  1027.                                    }
  1028.                                   else
  1029.                                     if (   !y
  1030.                                         || y == year)
  1031.                                      {
  1032.                                        if (adate_set)
  1033.                                         {
  1034.                                           m = MONTH_MIN;
  1035.                                           td = day_of_year (d, m, year) + 1;
  1036.                                         }
  1037.                                        else
  1038.                                          td = day_of_year (d, m, year) + 1;
  1039.                                      }
  1040.                                     else
  1041.                                       td = ed + 1;
  1042.                                   if (   (td <= ed)
  1043.                                       && (td >= day))
  1044.                                     print_line = TRUE;
  1045.                                 }
  1046.                              }
  1047.                             else
  1048.                               if (   !y
  1049.                                   || y == year
  1050.                                   || y == year+1)
  1051.                                {
  1052.                                  i = act_day - (SYEAR(wd, start_day));
  1053.                                  if (d < i)
  1054.                                   {
  1055.                                     m = MONTH_MIN;
  1056.                                     if (!y)
  1057.                                       y = year + 1;
  1058.                                     if (y == year+1)
  1059.                                      {
  1060.                                        td = day_of_year (d, m, y) + DAY_LAST + is_leap_year;
  1061.                                        incr_year = 1;
  1062.                                      }
  1063.                                   }
  1064.                                  else
  1065.                                    if (   !y
  1066.                                        || y == year)
  1067.                                      td = day_of_year (d, m, year);
  1068.                                  if (   (td < ed)
  1069.                                      && (td >= day))
  1070.                                    print_line = TRUE;
  1071.                                }
  1072.                           }
  1073.                      }
  1074.                 }
  1075.                else
  1076.                  if (   y >= 0
  1077.                      || y == year)
  1078.                   {
  1079.                     if (   (   (   rc_month_flag
  1080.                                 || rc_week_flag
  1081.                                 || rc_period_flag)
  1082.                             && m
  1083.                             && !d)
  1084.                         || (   (   rc_month_flag
  1085.                                 || rc_week_flag)
  1086.                             && !m
  1087.                             && !d)
  1088.                         || (   (   rc_year_flag
  1089.                                 || rc_period_list)
  1090.                             && (   !m
  1091.                                 || !d)))
  1092.                       ;   /* Ignore those entries !! */
  1093.                     else
  1094.                      {
  1095.                        if (!y)
  1096.                          y = year;
  1097.                        if (!m)
  1098.                         {
  1099.                           m = month;
  1100.                           (void)jdate2sdate (day, is_leap_year, &dd, &mm);
  1101.                           if (   (dd > d)
  1102.                               && (mm == m))
  1103.                             m++;
  1104.                           else
  1105.                             if (   (dd < d)
  1106.                                 && (mm < m))
  1107.                               m--;
  1108.                         }
  1109.                        if (valid_date (d, m, y))
  1110.                         {
  1111.                           td = day_of_year (d, m, y);
  1112.                           if (   (td >= day)
  1113.                               && (td < ed))
  1114.                             print_line = TRUE;
  1115.                         }
  1116.                      }
  1117.                   }
  1118.              }
  1119.           }
  1120.          else
  1121.            if (   !rc_period_flag
  1122.                && !rc_week_flag
  1123.                && !rc_month_flag
  1124.                && !rc_year_flag)
  1125.             {
  1126.               /*
  1127.                  Simple month-/year month mode (NO explicit date is given in command line):
  1128.                    manage -c[...]t arguments
  1129.               */
  1130.               dd = act_day;
  1131.               mm = month;
  1132.               yy = year;
  1133.               if (rc_tomorrow_flag)
  1134.                 next_date (&dd, &mm, &yy);
  1135.               if (   (   !y
  1136.                       || y == year
  1137.                       || (   rc_tomorrow_flag
  1138.                           && (ed > DAY_LAST+is_leap_year+1)
  1139.                           && (y == year+1)
  1140.                           && (   !m
  1141.                               || m == mm)))
  1142.                   && (   !m
  1143.                       || m == month
  1144.                       || (   rc_tomorrow_flag
  1145.                           && (m == mm)
  1146.                           && (   !y
  1147.                               || (   (ed > DAY_LAST+is_leap_year+1)
  1148.                                   && (y == year+1))
  1149.                               || (   (ed <= DAY_LAST+is_leap_year+1)
  1150.                                   && (y == year))))))
  1151.                {
  1152.                  if (is_weekday_mode)
  1153.                   {
  1154.                     /*
  1155.                        Respect short day name entry `yyyymmww[w]' ... (ww[w]==short dayname)
  1156.                     */
  1157.                     i = weekday_of_date (act_day, month, year);
  1158.                     j = 0;
  1159.                     if (rc_tomorrow_flag)
  1160.                       j = (d == weekday_of_date (dd, mm, yy));
  1161.                     if (   (   (d == i)
  1162.                             && (ed <= DAY_LAST+is_leap_year+1)
  1163.                             && (   !m
  1164.                                 || m == month))
  1165.                         || (   (d == i)
  1166.                             && (   (ed > DAY_LAST+is_leap_year+1)
  1167.                                 && (   (   !y
  1168.                                         && (   !m
  1169.                                             || m == month))
  1170.                                     || y == year)))
  1171.                         || (   j
  1172.                             && (   !m
  1173.                                 || m == month+1
  1174.                                 || m == mm)
  1175.                             && (   !y
  1176.                                 || (   (ed > DAY_LAST+is_leap_year+1)
  1177.                                     && (y == year+1))
  1178.                                 || (   (ed <= DAY_LAST+is_leap_year+1)
  1179.                                     && (y == year)))))
  1180.                      {
  1181.                        if (j)
  1182.                         {
  1183.                           m = mm;
  1184.                           d = dd;
  1185.                           if (   rc_tomorrow_flag
  1186.                               && (yy != year))
  1187.                             incr_year = 1;
  1188.                         }
  1189.                        else
  1190.                         {
  1191.                           m = month;
  1192.                           d = act_day;
  1193.                         }
  1194.                        if (   rc_tomorrow_flag
  1195.                            && !rc_have_today_in_list
  1196.                            && (d != dd))
  1197.                          ;   /* Void, skip those entries */
  1198.                        else
  1199.                          print_line = TRUE;
  1200.                      }
  1201.                   }
  1202.                  else
  1203.                    if (   !d
  1204.                        || (   (d == act_day)
  1205.                            && (   !m
  1206.                                || m == month)
  1207.                            && (   !y
  1208.                                || y == year))
  1209.                        || (   (d == dd)
  1210.                            && (   mm == month
  1211.                                || (   rc_tomorrow_flag
  1212.                                    && (   (   !m
  1213.                                            && (ed <= DAY_LAST+is_leap_year+1)
  1214.                                            && (   !y
  1215.                                                || y == year))
  1216.                                        || m == month+1
  1217.                                        || m == mm)))))
  1218.                     {
  1219.                       if (rc_tomorrow_flag)
  1220.                        {
  1221.                          if (   !d
  1222.                              && (   !m
  1223.                                  || (   mm == month
  1224.                                      || m == month+1
  1225.                                      || m == mm)))
  1226.                           {
  1227.                             if (   (yy > year)
  1228.                                 && (   d
  1229.                                     || m
  1230.                                     || y))
  1231.                              {
  1232.                                if (   !y
  1233.                                    || y == yy)
  1234.                                 {
  1235.                                   m = mm;
  1236.                                   d = dd;
  1237.                                   incr_year = 1;
  1238.                                 }
  1239.                              }
  1240.                             else
  1241.                               if (   m
  1242.                                   || y != year
  1243.                                   || ed <= DAY_LAST+is_leap_year+1)
  1244.                                {
  1245.                                  if (   !d
  1246.                                      && m
  1247.                                      && (mm != month)
  1248.                                      && (   !y
  1249.                                          || y == year))
  1250.                                   {
  1251.                                     m = mm;
  1252.                                     d = dd;
  1253.                                   }
  1254.                                  else
  1255.                                   {
  1256.                                     if (rc_have_today_in_list)
  1257.                                       print_twice++;
  1258.                                     else
  1259.                                      {
  1260.                                        m = mm;
  1261.                                        d = dd;
  1262.                                        if (yy != year)
  1263.                                          incr_year = 1;
  1264.                                      }
  1265.                                   }
  1266.                                }
  1267.                           }
  1268.                          else
  1269.                           {
  1270.                             if (   (d == dd)
  1271.                                 && (   !m
  1272.                                     || m == mm))
  1273.                              {
  1274.                                m = mm;
  1275.                                if (ed > DAY_LAST+is_leap_year+1)
  1276.                                  incr_year = 1;
  1277.                              }
  1278.                           }
  1279.                        }
  1280.                       if (!m)
  1281.                         m = month;
  1282.                       if (!d)
  1283.                         d = act_day;
  1284.                       if (   rc_tomorrow_flag
  1285.                           && !rc_have_today_in_list
  1286.                           && (d != dd))
  1287.                         ;   /* Void, skip those entries */
  1288.                       else
  1289.                         print_line = TRUE;
  1290.                     }
  1291.                }
  1292.             }
  1293.        }
  1294.     }
  1295.    /*
  1296.       Avoid incorrect assignment in case fixed date mentioned occurred
  1297.         during the missing period in month of Gregorian reformation
  1298.    */
  1299.    if (   print_line
  1300.        && (year+incr_year-decr_year == GREG_YEAR)
  1301.        && (m == GREG_MONTH)
  1302.        && (   (d >= GREG_F_DAY)
  1303.            && (d <= GREG_L_DAY)))
  1304.      print_line = FALSE;
  1305.    /*
  1306.       If 3-month mode is wanted, insert only those fixed date warnings
  1307.         which occur in that period
  1308.    */
  1309.    if (   print_line
  1310.        && (   is_3month_mode
  1311.            || is_3month_mode2))
  1312.     {
  1313.       register int  m2=fiscal_month+1;
  1314.       register int  m3=fiscal_month+2;
  1315.  
  1316.  
  1317.       if (fiscal_month >= MONTH_MAX-1)
  1318.        {
  1319.          m3 = MONTH_MIN;
  1320.          if (fiscal_month == MONTH_MAX)
  1321.           {
  1322.             m2 = MONTH_MIN;
  1323.             m3++;
  1324.           }
  1325.        }
  1326.       if (   (m != fiscal_month)
  1327.           && (m != m2)
  1328.           && (m != m3))
  1329.         print_line = FALSE;
  1330.     }
  1331.    /*
  1332.       Insert current line into `rc_table' now!
  1333.         (lines with no `text'-part are valid and are displayed)
  1334.    */
  1335.    if (   is_2easter
  1336.        || is_2dvar)
  1337.      print_twice++;
  1338.    if (print_line)
  1339.     {
  1340.       auto     Slint  num=0L;
  1341.       register int    k;
  1342.       register int    len_fn=len_year_max+5;
  1343.       register int    tmp_year=year;
  1344.       auto     Bool   ok;
  1345.  
  1346.  
  1347.       if (rc_enable_fn_flag)
  1348.         len_fn += (int)strlen(filename) + 3;
  1349.       /*
  1350.          Buffer fixed date text
  1351.       */
  1352.       if (print_twice > 1)
  1353.         strcpy(str, ptr_char);
  1354.       do
  1355.        {
  1356.          /*
  1357.             Check current line for %... macros
  1358.          */
  1359.          j=k = 0;
  1360.          while (MY_ISSPACE(*ptr_char))
  1361.            ptr_char++;
  1362.          ok = FALSE;
  1363.          while (!ok)
  1364.           {
  1365.             while (   *(ptr_char + j)
  1366.                    && (k < MAXLEN-len_fn))
  1367.              {
  1368.                if (*(ptr_char + j) == RC_MACRO_CHAR)
  1369.                 {
  1370.                   if (j)
  1371.                    {
  1372.                      /*
  1373.                         Check if %... macro is quoted
  1374.                      */
  1375.                      if (*(ptr_char + (j - 1)) == QUOTE_CHAR)
  1376.                        k--;
  1377.                      else
  1378.                        break;
  1379.                    }
  1380.                   else
  1381.                     break;
  1382.                 }
  1383.                s[k++] = *(ptr_char + j++);
  1384.              }
  1385.             if (k >= MAXLEN-len_fn)
  1386.               ok = TRUE;
  1387.             if (   !ok
  1388.                 && *(ptr_char + j))
  1389.              {
  1390.                auto Bool  is_b;
  1391.                auto Bool  is_s;
  1392.                auto Bool  is_e;
  1393.                auto Bool  is_t;
  1394.                auto Bool  is_d;
  1395.                auto Bool  is_w;
  1396.                auto Bool  is_m;
  1397.                auto Bool  is_y;
  1398.                auto Bool  is_n;
  1399.  
  1400.  
  1401.                /*
  1402.                   `%'-character (macro prefix) found!
  1403.                */
  1404.                j++;
  1405.                is_b = (Bool)(tolower(*(ptr_char+j)) == RC_BYEAR_CHAR);
  1406.                is_s = (Bool)(tolower(*(ptr_char+j)) == RC_SDATE_CHAR);
  1407.                is_e = (Bool)(tolower(*(ptr_char+j)) == RC_EDATE_CHAR);
  1408.                is_t = (Bool)(tolower(*(ptr_char+j)) == RC_TIME_CHAR);
  1409.                is_d = (Bool)(tolower(*(ptr_char+j)) == RC_DAY_CHAR);
  1410.                is_w = (Bool)(tolower(*(ptr_char+j)) == RC_WEEK_CHAR);
  1411.                is_m = (Bool)(tolower(*(ptr_char+j)) == RC_MONTH_CHAR);
  1412.                is_y = (Bool)(tolower(*(ptr_char+j)) == RC_YEAR_CHAR);
  1413.                is_n = (Bool)(tolower(*(ptr_char+j)) == RC_DATE_CHAR);
  1414.                /*
  1415.                   Check for
  1416.                     %n[[+|-]<n>] or
  1417.                     %s[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@..., %s`yyyy'*... or
  1418.                     %e[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %e`yyyy'@..., %e`yyyy'*... or
  1419.                     %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %b`yyyy'@..., %b`yyyy'*... or
  1420.                     %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %y`yyyy'@..., %y`yyyy'*... macros
  1421.                */
  1422.                if (   is_n
  1423.                    || is_s
  1424.                    || is_e
  1425.                    || is_b
  1426.                    || (   is_y
  1427.                        && *(ptr_char + j + 1)
  1428.                        && !MY_ISSPACE(*(ptr_char+j+1))))
  1429.                 {
  1430.                   j++;
  1431.                   if (!is_n)
  1432.                    {
  1433.                      (void)rc_get_date (ptr_char+j, &is_weekday_mode, &dd, &mm, &yy, &nn, &len,
  1434.                                         &hhc, &hhn, &hhwd, filename, *line, line_buffer, TRUE);
  1435.                      j += len;
  1436.                      if (!yy)
  1437.                       {
  1438.                         if (fiscal_month > MONTH_MIN)
  1439.                           yy = y;
  1440.                         else
  1441.                           yy = year;
  1442.                       }
  1443.                      /*
  1444.                         Respect possible fiscal year
  1445.                      */
  1446.                      if (yy != -1)
  1447.                       {
  1448.                         yy -= incr_year;
  1449.                         yy += decr_year;
  1450.                       }
  1451.                      /*
  1452.                         If @... date part is given,
  1453.                           compute the according date
  1454.                      */
  1455.                      if (hhc == RC_EASTER_CHAR)
  1456.                       {
  1457.                         if (fiscal_month > MONTH_MIN)
  1458.                          {
  1459.                            if (!precomp_date (hhn, hhwd, &dd, &mm, yy+incr_year, EAster))
  1460.                              yy = -1;
  1461.                          }
  1462.                         else
  1463.                           if (!precomp_date (hhn, hhwd, &dd, &mm, yy, EAster))
  1464.                             yy = -1;
  1465.                       }
  1466.                      else
  1467.                        if (islower(hhc))
  1468.                         {
  1469.                           if (rc_dvar[IDX(hhc)].l.month)
  1470.                            {
  1471.                              mm = (int)rc_dvar[IDX(hhc)].l.month;
  1472.                              dd = (int)rc_dvar[IDX(hhc)].l.day;
  1473.                            }
  1474.                           else
  1475.                             if (rc_dvar[IDX(hhc)].g.month)
  1476.                              {
  1477.                                mm = (int)rc_dvar[IDX(hhc)].g.month;
  1478.                                dd = (int)rc_dvar[IDX(hhc)].g.day;
  1479.                              }
  1480.                           if (fiscal_month > MONTH_MIN)
  1481.                            {
  1482.                              if (!precomp_date (hhn, hhwd, &dd, &mm, yy+incr_year, DVar))
  1483.                                yy = -1;
  1484.                            }
  1485.                           else
  1486.                             if (!precomp_date (hhn, hhwd, &dd, &mm, yy, DVar))
  1487.                               yy = -1;
  1488.                         }
  1489.                        else
  1490.                          if (   hhc == 'D'
  1491.                              || hhc == 'W')
  1492.                           {
  1493.                             if (fiscal_month > MONTH_MIN)
  1494.                              {
  1495.                                auto int  yyy=yy+incr_year;
  1496.  
  1497.  
  1498.                                if (!precomp_nth_wd (hhn, hhwd, &hhn, &dd, &mm, &yyy,
  1499.                                                     ((hhc == 'D') ? DAy : WEek)))
  1500.                                  yy = yyy;
  1501.                              }
  1502.                             else
  1503.                               (void)precomp_nth_wd (hhn, hhwd, &hhn, &dd, &mm, &yy,
  1504.                                                     ((hhc == 'D') ? DAy : WEek));
  1505.                           }
  1506.                      if (len > len_year_max)
  1507.                        len -= len_year_max;
  1508.                      else
  1509.                        len = 0;
  1510.                      /*
  1511.                         %s[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1512.                           starting year macro found
  1513.                      */
  1514.                      if (is_s)
  1515.                       {
  1516.                         /*
  1517.                            Assume current/first month of year
  1518.                         */
  1519.                         if (!mm)
  1520.                          {
  1521.                            if (len >= 1)
  1522.                             {
  1523.                               mm = m;
  1524.                               if (len == 2)
  1525.                                 len -= 2;
  1526.                               else
  1527.                                 len--;
  1528.                             }
  1529.                            else
  1530.                              mm = MONTH_MIN;
  1531.                          }
  1532.                         else
  1533.                          {
  1534.                            if (len == 2)
  1535.                              len -= 2;
  1536.                            else
  1537.                              len--;
  1538.                          }
  1539.                         /*
  1540.                            Assume current/first day of month
  1541.                         */
  1542.                         if (!dd)
  1543.                          {
  1544.                            if (len >= 1)
  1545.                              dd = d;
  1546.                            else
  1547.                              dd = DAY_MIN;
  1548.                          }
  1549.                       }
  1550.                      else
  1551.                        /*
  1552.                           %e[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1553.                             ending year macro found
  1554.                        */
  1555.                        if (is_e)
  1556.                         {
  1557.                           /*
  1558.                              Assume current/last month of year
  1559.                           */
  1560.                           if (!mm)
  1561.                            {
  1562.                              if (len >= 1)
  1563.                               {
  1564.                                 mm = m;
  1565.                                 if (len == 2)
  1566.                                   len -= 2;
  1567.                                 else
  1568.                                   len--;
  1569.                               }
  1570.                              else
  1571.                                mm = MONTH_MAX;
  1572.                            }
  1573.                           else
  1574.                            {
  1575.                              if (len == 2)
  1576.                                len -= 2;
  1577.                              else
  1578.                                len--;
  1579.                            }
  1580.                           /*
  1581.                              Assume current/last day of month
  1582.                           */
  1583.                           if (!dd)
  1584.                            {
  1585.                              if (len >= 1)
  1586.                                dd = d;
  1587.                              else
  1588.                               {
  1589.                                 if (mm == 2)
  1590.                                  {
  1591.                                    if (fiscal_month > MONTH_MIN)
  1592.                                      dd = days_of_february (yy+incr_year);
  1593.                                    else
  1594.                                      dd = days_of_february (yy);
  1595.                                  }
  1596.                                 else
  1597.                                   dd = dvec[mm-1];
  1598.                               }
  1599.                            }
  1600.                         }
  1601.                        else
  1602.                         /*
  1603.                            %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1604.                              birth year macro or
  1605.                            %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1606.                              year macro found
  1607.                         */
  1608.                         {
  1609.                           /*
  1610.                              Assume current month/day
  1611.                           */
  1612.                           if (!mm)
  1613.                             mm = m;
  1614.                           if (!dd)
  1615.                             dd = d;
  1616.                         }
  1617.                      /*
  1618.                         If special value 99 for day `dd' is given,
  1619.                           set day to last day of month
  1620.                      */
  1621.                      if (dd == 99)
  1622.                       {
  1623.                         /*
  1624.                            Assume last day of month
  1625.                         */
  1626.                         if (mm == 2)
  1627.                          {
  1628.                            if (   is_e
  1629.                                && (fiscal_month > MONTH_MIN))
  1630.                              dd = days_of_february (yy+incr_year);
  1631.                            else
  1632.                              dd = days_of_february (yy);
  1633.                          }
  1634.                         else
  1635.                           dd = dvec[mm-1];
  1636.                       }
  1637.                      /*
  1638.                         If "n'th weekday of month" entry set,
  1639.                           compute the according date
  1640.                      */
  1641.                      if (nn)
  1642.                        nth_weekday_of_month (&dd, &mm, &yy, &nn, &is_weekday_mode);
  1643.                      /*
  1644.                         Compute the day difference of the two dates
  1645.                      */
  1646.                      if (yy >= 0)
  1647.                       {
  1648.                         if (   !nn
  1649.                             && (   fiscal_month > MONTH_MIN
  1650.                                 || (   incr_year
  1651.                                     && (   rc_tomorrow_flag
  1652.                                         || rc_week_flag))))
  1653.                           yy += incr_year;
  1654.                         num = d_between (dd, mm, yy, d, m, (y) ? y : year+incr_year);
  1655.                         /*
  1656.                            Starting date of event greater current date resp.,
  1657.                              ending date of event smaller current date:
  1658.                              --> avoid displaying of fixed date text
  1659.                         */
  1660.                         if (is_s)
  1661.                          {
  1662.                            if (num < 0L)
  1663.                             {
  1664.                               ok = TRUE;
  1665.                               print_line = FALSE;
  1666.                             }
  1667.                          }
  1668.                         else
  1669.                           if (is_e)
  1670.                            {
  1671.                              if (num > 0L)
  1672.                               {
  1673.                                 ok = TRUE;
  1674.                                 print_line = FALSE;
  1675.                               }
  1676.                            }
  1677.                           else
  1678.                            /*
  1679.                               Manage
  1680.                                 %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1681.                                   birth year macros and
  1682.                                 %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...
  1683.                                   year macros
  1684.                            */
  1685.                            {
  1686.                              if (is_b)
  1687.                               {
  1688.                                 yy = ((y) ? y : year+incr_year) - yy;
  1689.                                 if (   m < mm
  1690.                                     || (   (m == mm)
  1691.                                         && (d < dd)))
  1692.                                   yy--;
  1693.                               }
  1694.                              else
  1695.                               {
  1696.                                 /*
  1697.                                    is_y
  1698.                                 */
  1699.                                 yy = yy - ((y) ? y : year+incr_year);
  1700.                                 if (   m < mm
  1701.                                     || (   (m == mm)
  1702.                                         && (d < dd)))
  1703.                                  {
  1704.                                    if (yy < 1)
  1705.                                      yy++;
  1706.                                    else
  1707.                                      if (yy > 1)
  1708.                                        yy--;
  1709.                                  }
  1710.                               }
  1711.                              if (   is_b
  1712.                                  && (yy < 1))
  1713.                                ;   /* Void, don't manage resp., suppress such dates */
  1714.                              else
  1715.                               {
  1716.                                 /*
  1717.                                    Print year difference
  1718.                                 */
  1719.                                 sprintf(s2, "%d", yy);
  1720.                                 i = 0;
  1721.                                 while (   s2[i]
  1722.                                        && (k < MAXLEN-len_fn))
  1723.                                   s[k++] = s2[i++];
  1724. #  if !USE_GER
  1725.                                 if (is_b)
  1726.                                  {
  1727.                                    sprintf(s2, "%s", day_suffix (yy));
  1728.                                    i = 0;
  1729.                                    while (   s2[i]
  1730.                                           && (k < MAXLEN-len_fn))
  1731.                                      s[k++] = s2[i++];
  1732.                                  }
  1733. #  endif /* !USE_GER */
  1734.                               }
  1735.                            }
  1736.                         if (!*(ptr_char + j))
  1737.                           ok = TRUE;
  1738.                         else
  1739.                           if (   (*(ptr_char + j) == ' ')
  1740.                               && (s[k-1] == ' '))
  1741.                             k--;
  1742.                       }
  1743.                      else
  1744.                        if (   (*(ptr_char + j) == ' ')
  1745.                            && (s[k-1] == ' '))
  1746.                          k--;
  1747.                    }
  1748.                   else
  1749.                    {
  1750.                      auto Slint  jdate;
  1751.  
  1752.  
  1753.                      /*
  1754.                         %n[[+|-]<n>] macro found
  1755.                      */
  1756.                      i = 0;
  1757.                      while (   *(ptr_char + j) == *ASC_LIT
  1758.                             || *(ptr_char + j) == *DES_LIT
  1759.                             || isdigit(*(ptr_char+j)))
  1760.                       {
  1761.                         if (i < MAXLEN)
  1762.                           s2[i++] = *(ptr_char + j);
  1763.                         j++;
  1764.                       }
  1765.                      s2[i] = '\0';
  1766.                      num = atol(s2);
  1767.                      y = year + incr_year - decr_year;
  1768.                      jdate = (Slint)date2num (d, m, y);
  1769.                      if (   (jdate+num <= (Slint)date2num (dvec[MONTH_MAX-1], MONTH_MAX, YEAR_MAX))
  1770.                          && (jdate+num >= 1L))
  1771.                       {
  1772.                         num2date (jdate+num, &dd, &mm, &yy);
  1773. #  if USE_GER
  1774.                         sprintf(s2, "%02d-%s-%0*d", dd,
  1775.                                 short_month_name (mm), len_year_max, yy);
  1776. #  else /* !USE_GER */
  1777.                         sprintf(s2, "%s-%02d-%0*d", short_month_name (mm),
  1778.                                 dd, len_year_max, yy);
  1779. #  endif /* !USE_GER */
  1780.                         i = 0;
  1781.                         while (   s2[i]
  1782.                                && (k < MAXLEN-len_fn))
  1783.                           s[k++] = s2[i++];
  1784.                       }
  1785.                      else
  1786.                        if (   (*(ptr_char + j) == ' ')
  1787.                            && (s[k-1] == ' '))
  1788.                          k--;
  1789.                    }
  1790.                 }
  1791.                else
  1792.                 {
  1793.                   /*
  1794.                      %-character (macro prefix) found:
  1795.                        check for simple %t[12|24], %d, %w, %m and %y macros
  1796.                   */
  1797.                   if (   is_t
  1798.                       || is_d
  1799.                       || is_w
  1800.                       || is_m
  1801.                       || is_y)
  1802.                    {
  1803.                      if (is_t)
  1804.                       {
  1805.                         register int   tmp_ah=act_hour;
  1806.                         auto     char  time_suffix[3];
  1807.                         auto     Bool  is_12_hours_format=FALSE;
  1808.  
  1809.  
  1810.                         /*
  1811.                            Simple %t[12|24] macro found:
  1812.                              replace it by the current system time hh:mm[am|pm]
  1813.                         */
  1814.                         j++;
  1815.                         if (isdigit(*(ptr_char+j)))
  1816.                          {
  1817.                            if (*(ptr_char + j) == '1')
  1818.                              is_12_hours_format = TRUE;
  1819.                            while (isdigit(*(ptr_char+j)))
  1820.                              j++;
  1821.                          }
  1822.                         j--;
  1823.                         if (is_12_hours_format)
  1824.                          {
  1825.                            /*
  1826.                               Copy trailing "am" resp., "pm" to text
  1827.                            */
  1828.                            if (tmp_ah >= 12)
  1829.                             {
  1830.                               strcpy(time_suffix, RC_PM_TXT);
  1831.                               if (tmp_ah > 12)
  1832.                                 tmp_ah -= 12;
  1833.                             }
  1834.                            else
  1835.                              strcpy(time_suffix, RC_AM_TXT);
  1836.                          }
  1837.                         else
  1838.                           *time_suffix = '\0';
  1839.                         sprintf(s2, "%s%02d"TIME_SEP"%02d%s%s",
  1840.                                 (!highlight_flag) ? "" : ehls1s.seq,
  1841.                                 tmp_ah, act_min, time_suffix,
  1842.                                 (!highlight_flag) ? "" : ehls1e.seq);
  1843.                       }
  1844.                      else
  1845.                       {
  1846.                         auto Slint  diff;
  1847.  
  1848.  
  1849.                         /*
  1850.                            Simple %d, %w, %m or %y macros found:
  1851.                              replace it by the according, computed number
  1852.                         */
  1853.                         dd = act_day;
  1854.                         mm = act_month;
  1855.                         yy = act_year;
  1856.                         (void)get_actual_date ();
  1857.                         y = year + incr_year - decr_year;
  1858.                         /*
  1859.                            Now compute the differences:
  1860.                              date1 == actual (base)date (act_day, act_month, act_year)
  1861.                              date2 == reported date (d, m, y)
  1862.                         */
  1863.                         if (is_d)
  1864.                           diff = d_between (act_day, act_month, act_year, d, m, y);
  1865.                         else
  1866.                           if (is_w)
  1867.                             diff = w_between (act_day, act_month, act_year, d, m, y);
  1868.                           else
  1869.                             if (is_m)
  1870.                               diff = m_between (act_month, act_year, m, y);
  1871.                             else
  1872.                               /*
  1873.                                  Simple %y macro found
  1874.                               */
  1875.                               diff = (Slint)y - act_year;
  1876.                         sprintf(s2, "%ld", diff);
  1877.                         act_day = dd;
  1878.                         act_month = mm;
  1879.                         act_year = yy;
  1880.                       }
  1881.                      i = 0;
  1882.                      while (   s2[i]
  1883.                             && (k < MAXLEN-len_fn))
  1884.                        s[k++] = s2[i++];
  1885.                      j++;
  1886.                    }
  1887.                   else
  1888.                    {
  1889.                      j--;
  1890.                      s[j] = *(ptr_char + j);
  1891.                      k = ++j;
  1892.                    }
  1893.                 }
  1894.              }
  1895.             else
  1896.               ok = TRUE;
  1897.             if (   ok
  1898.                 || k >= MAXLEN-len_fn)
  1899.              {
  1900.                ok = TRUE;
  1901.                s[k] = '\0';
  1902.                strcpy(line_buffer, s);
  1903.                ptr_char = line_buffer;
  1904.              }
  1905.           }
  1906.          if (print_line)
  1907.           {
  1908.             if (rc_enable_fn_flag)
  1909.               sprintf(s, "%0*d%02d%02d (%s) %s",
  1910.                       len_year_max, year+incr_year-decr_year, m, d, filename, ptr_char);
  1911.             else
  1912.               sprintf(s, "%0*d%02d%02d %s",
  1913.                       len_year_max, year+incr_year-decr_year, m, d, ptr_char);
  1914.             /*
  1915.                Now compute whether a filler text for a week entry is needed:
  1916.                  week 53/1   == 7 chars text "|53/1| "  -> no filler text
  1917.                  week 1...53 == 5 chars text "|nn| "    -> 2 chars filler text
  1918.             */
  1919.             if (rc_weekno_flag)
  1920.               if (!week_number (d, m, year+incr_year-decr_year))
  1921.                 len_fil_wt = 2;
  1922.             /*
  1923.                Now place the fixed date into vector;
  1924.                  only if previous fixed date is equal to actual fixed date,
  1925.                  avoid insertation of actual fixed date!
  1926.             */
  1927.             k = 1;
  1928.             if (*rc_elems)
  1929.               k = strcmp(s, rc_table[*rc_elems-1]);
  1930.             /*
  1931.                Store the constructed "raw" line in `rc_table[]'
  1932.             */
  1933.             if (k)
  1934.              {
  1935.                 if (*rc_elems >= rc_elems_max)
  1936.                  {
  1937. #if HAVE_ASSERT_H
  1938.                    /*
  1939.                       Check if value for maximum number of table entries
  1940.                         fits to the positive range of a signed int(INT_MAX)!!
  1941.                    */
  1942.                    assert((Uint)rc_elems_max+RC_ELEMS_MAX<=testval);
  1943. #endif
  1944.                    /*
  1945.                       Resize the table
  1946.                    */
  1947.                    rc_elems_max += RC_ELEMS_MAX;
  1948.                    rc_table = (char **)my_realloc (rc_table, rc_elems_max*sizeof(char *),
  1949.                                                    124, __FILE__, __LINE__ -1,
  1950.                                                    "rc_elems", rc_elems_max);
  1951.                  }
  1952.                rc_table[*rc_elems] = (char *)my_malloc (strlen(s)+1,
  1953.                                                         124, __FILE__, __LINE__ -1,
  1954.                                                         "rc_elems", *rc_elems);
  1955.                strcpy(rc_table[(*rc_elems)++], s);
  1956.              }
  1957.           }
  1958.          /*
  1959.             Must we construct line more than once?
  1960.          */
  1961.          if (print_twice > 1)
  1962.           {
  1963.             /*
  1964.                Restore fixed date text
  1965.                  cause it's possible that we must evaluate the %... macros
  1966.                  again and the year has changed...
  1967.             */
  1968.             ptr_char = str;
  1969.             if (is_2easter)
  1970.              {
  1971.                /*
  1972.                   Precalculate next date relative to Easter Sunday
  1973.                */
  1974.                incr_year = 1;
  1975.                precomp_date (hn, hwd, &d, &m, year+incr_year, EAster);
  1976.              }
  1977.             else
  1978.               if (is_2dvar)
  1979.                {
  1980.                  /*
  1981.                     Precalculate next date relative to date variable
  1982.                       and use original date of `dvar', i.e. use buffer of day an month
  1983.                  */
  1984.                  incr_year = 1;
  1985.                  if (islower(hc))
  1986.                    (void)precomp_date (hn, hwd, &d2, &m2, year+incr_year, DVar);
  1987.                  else
  1988.                   {
  1989.                     y = year + incr_year;
  1990.                     (void)precomp_nth_wd (hn, hwd, &hn, &d2, &m2, &y,
  1991.                                           ((hc == 'D') ? DAy : WEek));
  1992.                   }
  1993.                  d = d2;
  1994.                  m = m2;
  1995.                }
  1996.               else
  1997.                 /*
  1998.                    Compute tomorrows date
  1999.                 */
  2000.                 next_date (&d, &m, &year);
  2001.             print_line = TRUE;
  2002.           }
  2003.        } while (--print_twice); /* I don't like the GNU-coding scheme for do-whiles */
  2004.       year = tmp_year;
  2005.     }
  2006.    month = tmp_month;
  2007. }
  2008. #endif /* USE_RC */
  2009.